package be.bejug.setris

import java.awt.Color

sealed case class	Tile(val color:Color)

object	Tiles {
	object	red	extends Tile(Color.RED)
	object	green	extends	Tile(Color.GREEN)
	object	blue	extends	Tile(Color.BLUE)
	object	yellow	extends	Tile(Color.YELLOW)
	object	cyan	extends	Tile(Color.CYAN)
	object	magenta	extends	Tile(Color.MAGENTA)
	object	orange	extends	Tile(Color.ORANGE)
	object	white	extends	Tile(Color.WHITE)

	val	allTiles	=	List(red,green,blue,yellow,cyan,magenta,orange,white)
}


/**
 * A TileGrid defines an immutable grid of tiles with a specific width and height.
 * Every position contains Some(Tile) or None
 */
case class TileGrid(val width:Int,val height:Int,private val field:Map[(Int,Int),Tile]){
	/**
	 * Empty TileGrid
	 */
	def	this(w:Int,h:Int) = this(w,h,Map())

	/**
	 * A new Empty TileGrid with the same width and hight
	 */
	def	clear = new TileGrid(width,height)

	/**
	 *  Get the Tile at the given position
	 */
	def apply(x:Int,y:Int):Option[Tile] = field.get(x,y)


	/**
	 * Set the Tile Option at the given position
	 */
	def	set(x:Int,y:Int,tile:Option[Tile]):TileGrid = {
		if(isValidPosition(x,y)){
			if(field.get(x,y) == tile){
				this
			} else {
				new TileGrid(width,height,
					tile match {
						case Some(t) => field + ((x,y) -> t)
						case None => field - Pair(x,y)
					}
				)
			}
		} else {
			this
		}
	}


	/**
	 * Check if the given position falls withing this grids boudaries
	 */
	private	def	isValidPosition(x:Int,y:Int) = x >=0 && x < width && y>=0 && y<height


	/**
	 * Get this TileGrid rotated 90 degrees to the left
	 * Because this is a lazy val, the rotated instances are
	 * automatically cached.
	 */
	lazy val	rotateLeft:TileGrid={
		var newField	=	Map[(Int,Int),Tile]()
		for(ix <-0 until width;
				iy <-0 until height){
			this(ix,iy).foreach(b => newField = newField + ((iy,width-1-ix) -> b))
		}
		new TileGrid(height,width,newField)
	}

	/**
	 * Create a new TileGrid that is rotated 90 degrees to the right
	 */
	lazy val	rotateRight	=	rotateLeft.rotateLeft.rotateLeft


	/**
	 * Draw another TileGrid over this one
	 */
	def	draw(x:Int,y:Int,f:TileGrid):TileGrid = {
		var	newField	=	field
		for(ix <-0 until f.width;
				iy <-0 until f.height){
			f(ix,iy).foreach(b => newField = newField + ((ix+x,iy+y) -> b))
		}
		new TileGrid(width,height,newField)
	}


	def	collision(x:Int,y:Int,f:TileGrid):Boolean = {
		for(ix <-0 until f.width;
				iy <-0 until f.height){
			f(ix,iy).foreach{ t=>
				if(this(ix+x,iy+y).isDefined){
					return	true
				}
			}
		}
		false
	}

  def	detectFullLine(y:Int):Boolean = {
		for(ix <-0 until this.width){
				if(!this(ix,y).isDefined){
					return false
				}
		}
		true
	}



	override	def toString = {
		(for(iy<-0 until height) yield
			((for(ix<-0 until width) yield this(ix,iy) match {
				case Some(t) => "#"
				case None => "."
			}).mkString(""))).mkString("\r\n")
	}

  def dropLine(line:Int) = {
    
  }
}
